package com.itheima.aop;

import cn.hutool.json.JSONUtil;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.utils.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Map;

@Slf4j
@Component
@Aspect //AOP类
public class OperateAspect {

    @Autowired
    OperateLogMapper operateLogMapper;

    @Autowired
    HttpServletRequest request; //自动注入获取请求对象 更加方便,但是有一定局限性

    //@Around("execution(* com.itheima.controller.*.*(..))") //切入点表达式
    @Around("@annotation(com.itheima.anno.Log)")
    public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        //1. 记录开始时间
        long begin = System.currentTimeMillis();


        //2. 调用原始方法运行
        Object result = joinPoint.proceed();


        //3. 记录结束时间, 计算方法执行耗时
        long end = System.currentTimeMillis();

        /*创建日志对象,添加到数据库*/
        OperateLog operateLog = new OperateLog();
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        operateLog.setMethodName(joinPoint.getSignature().getName());
        operateLog.setOperateTime(LocalDateTime.now());

        //operateLog.setReturnValue(result.toString());
        operateLog.setReturnValue(JSONUtil.toJsonStr(result));
        //operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs())); 获取的信息会有数组名
        operateLog.setMethodParams(JSONUtil.toJsonStr(joinPoint.getArgs()));
        operateLog.setCostTime(end - begin);

        //使用RequestContextHolder获取request对象 更加通用 但是比较繁琐
        // HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

        //从请求头中获取jwt，获取用户id
        String jwt = request.getHeader("token");
        Map<String, Object> map = JwtUtils.parseJwt(jwt);
        String userId = map.get("id").toString();
        operateLog.setOperateUser(Integer.valueOf(userId));
        operateLogMapper.insert(operateLog);

        /*返回执行的结果*/
        return result;
    }
}
